package com.misyi.designpattern.iterator;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;

/**
 * 迭代器模式
 *
 * @author licong
 * @date 2021-09-10 下午9:10
 */
public class IteratorPatternDemo {

    public static void main(String[] args) {
        Student student1 = new Student();
        student1.setName("小王");
        Student student2 = new Student();
        student2.setName("小明");

        Classroom classroom = new Classroom(8);
        classroom.addStudent(student1);
        classroom.addStudent(student2);

        Iterator<Student> studentIterator = classroom.iterator();
        // 此处就算修改了教室类里学生存储的结构, 调用方的代码也不用变动
        while (studentIterator.hasNext()) {
            System.out.println(studentIterator.next());
        }

    }

    /**
     * 定义一个可迭代的接口
     */
    public interface Aggregate<T> {

        Iterator<T> iterator();
    }

    /**
     * 定义一个迭代器接口
     */
    public interface Iterator<T> {

        /**
         * 判断是否有下一个元素
         */
        boolean hasNext();

        /**
         * 获取下一个元素
         */
        T next();
    }


    /**
     * 学生类
     */
    @Data
    public static class Student {

        private String name;

    }

    /**
     * 教室类
     */
    public static class Classroom implements Aggregate<Student>{

//        private final Student[] students;
        private final List<Student> students;

        // 最后一位学生的下标
        private int last = 0;

        // 教室类指定大小
        public Classroom(int size) {
//            this.students = new Student[size];
            this.students = new ArrayList<>(size);
        }

        public void addStudent(Student student) {
//            this.students[last] = student;
            this.students.add(student);
            last++;
        }

        public int getLength() {
            return last;
        }

        public Student getStudent(int index) {
//            return students[index];
            return students.get(index);
        }

        @Override
        public Iterator<Student> iterator() {
            return new ClassroomIterator(this);
        }
    }


    /**
     * 教师类迭代器
     */
    public static class ClassroomIterator implements Iterator<Student> {

        private final Classroom classroom;
        // 教室里数到的人数
        private int index;

        public ClassroomIterator(Classroom classroom) {
            this.classroom = classroom;
            this.index = 0;
        }

        @Override
        public boolean hasNext() {
            return classroom.getLength() > index;
        }
        
        @Override
        public Student next() {
            Student student = classroom.getStudent(index);
            index++;
            return student;
        }
    }
}
